import 'package:inmotion_protocol/base/base_factory.dart';
import 'package:inmotion_protocol/common/compact.dart';
import 'package:inmotion_protocol/common/product_version.dart';
import 'package:inmotion_protocol/common/vehicle_info.dart';
import 'package:inmotion_protocol/lorin/constant.dart';
import 'package:inmotion_protocol/lorin/factory/special/scooter/scooter_message_factory.dart';
import 'package:inmotion_protocol/lorin/lorin_message.dart';
import 'package:inmotion_protocol/lorin/bean/scooter/scooter_settings.dart';
import 'package:inmotion_protocol/util/byte_util.dart';

class RsVeloMessageFactory extends ScooterLorinSpecialMessageFactory<_RsVeloCmd>
    implements FullBMSFeatureMsgFactoryTrait<LorinMessage> {
  RsVeloMessageFactory(ProductProperty productProperty)
      : super(productProperty);

  @override
  void initCompact(int apiVersion, VersionWrapper version) {
    compact = RsVeloCmdDefault();
  }

  /// LR1骑行模式定义不同
  @override
  LorinMessage genSetRidingModeMsg(int mode) {
    switch (mode) {
      case ScooterSettings.ridingModeP:
        mode = 0;
        break;
      case ScooterSettings.ridingModeEco:
        mode = 1;
        break;
      case ScooterSettings.ridingModeNormal:
        mode = 2;
        break;
      case ScooterSettings.ridingModeSport:
        mode = 3;
        break;
      case ScooterSettings.ridingModeX:
        mode = 4;
        break;
    }
    return super.genSetRidingModeMsg(mode);
  }

  LorinMessage genAccForceMsg(int type, int force) {
    return genSpecialOne2OneWriteMsg(
        compact!.accForceCmd(),
        ByteUtil.buildBytes(
            ByteUtil.num2BytesLe(type, 1), ByteUtil.num2BytesLe(force, 1)));
  }

  LorinMessage genBrakeForceMsg(int type, int force) {
    return genSpecialOne2OneWriteMsg(
        compact!.brakeForceCmd(),
        ByteUtil.buildBytes(
            ByteUtil.num2BytesLe(type, 1), ByteUtil.num2BytesLe(force, 1)));
  }

  LorinMessage genOnePedalModeOnOffMsg(bool on) {
    return genSpecialOne2OneWriteMsg(
        compact!.onePedalModeCmd(), ByteUtil.bool2Bytes(on));
  }

  LorinMessage genBrakeFirstModeOnOffMsg(bool on) {
    // 协议定义0为开，1为关
    return genSpecialOne2OneWriteMsg(
        compact!.brakeFirstModeCmd(), ByteUtil.bool2Bytes(!on));
  }

  LorinMessage genSetStandbyTimeMsg(int seconds) {
    return genSpecialOne2OneWriteMsg(
        compact!.standbyTimeCmd(), ByteUtil.num2BytesLe(seconds ~/ 60, 2));
  }

  LorinMessage genSetParkTimeMsg(int seconds) {
    return genSpecialOne2OneWriteMsg(
        compact!.parkTimeCmd(), ByteUtil.num2BytesLe(seconds, 1));
  }

  @override
  LorinMessage genTBoxDeviceId() {
    return genSpecialOne2OneReadMsg(
        compact!.tBoxDeviceId(), null, null, false, null, Constant.deviceTBox);
  }

  LorinMessage genTboxLowBatLevelWakeUpVehicleModeOnOffMsg(bool on){
    return genSpecialOne2OneWriteMsg(
      compact!.lowBatteryWakeUpVehicleModeCmd(), ByteUtil.bool2Bytes(on)
    );
  }

  @override
  LorinMessage genCalibrateHandleMsg(int which) {
    if (which == ScooterSettings.calibrationHandleIMU) which = 1;
    return super.genCalibrateHandleMsg(which);
  }

  @override
  LorinMessage genQueryHandleCalibrationResultMsg(int which,
      [int? source, int? target]) {
    if (which == ScooterSettings.calibrationHandleIMU) which = 1;
    return super.genQueryHandleCalibrationResultMsg(which, source, target);
  }

  @override
  LorinMessage genRequestBMSRealTimeInfoMsg(int target) {
    return genSpecialMany2ManyReadMsg(
        null, target, compact!.bmsRealTimeInfoCmd());
  }

  @override
  LorinMessage genRequestBMSFixedInfoMsg(int target) {
    return genSpecialMany2ManyReadMsg(null, target, compact!.bmsFixedInfoCmd());
  }

  @override
  LorinMessage genRequestBMSCellsVoltageInfoMsg(int target) {
    return genSpecialMany2ManyReadMsg(
        null, target, compact!.bmsCellsVoltageCmd());
  }

  @override
  LorinMessage genRequestBMSDateMsg(int target) {
    return genSpecialMany2ManyReadMsg(null, target, compact!.bmsDateCmd());
  }
}

abstract class _RsVeloCmd extends ScooterCmdCompact
    implements FullBMSFeatureCmdTrait {
  int accForceCmd();

  int brakeForceCmd();

  int onePedalModeCmd();

  int brakeFirstModeCmd();

  int standbyTimeCmd();

  int parkTimeCmd();

  int lowBatteryWakeUpVehicleModeCmd();
}

class RsVeloCmdDefault extends _RsVeloCmd {
  @override
  int accForceCmd() {
    return 15;
  }

  @override
  int brakeForceCmd() {
    return 16;
  }

  @override
  int ridingModeCmd() {
    return 17;
  }

  @override
  int lockCmd() {
    return 18;
  }

  @override
  int safeSpeedLimitCmd() {
    return 19;
  }

  @override
  int onePedalModeCmd() {
    return 20;
  }

  @override
  int brakeFirstModeCmd() {
    return 21;
  }

  @override
  int standbyTimeCmd() {
    return 22;
  }

  @override
  int parkTimeCmd() {
    return 24;
  }

  @override
  int lowBatteryWakeUpVehicleModeCmd() {
    return 25;
  }

  @override
  int shutdownCmd() {
    return 30;
  }

  @override
  int headlightOnOffCmd() {
    return 31;
  }

  @override
  int calibrateCmd() {
    return 32;
  }

  @override
  int calibrationResultCmd() {
    return 33;
  }

  @override
  int bmsRealTimeInfoCmd() {
    return 0x01;
  }

  @override
  int bmsCellsVoltageCmd() {
    return 0x02;
  }

  @override
  int bmsDateCmd() {
    return 0x03;
  }

  @override
  int bmsFixedInfoCmd() {
    return 0x04;
  }
}
